/*
 *  Copyright (C) 2010 Glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.swing.builder;

import javax.swing.JPanel;
import org.balisunrise.annotation.util.AnnotationsUtilitiesException;
import org.balisunrise.annotation.util.NameUtil;
import org.balisunrise.annotation.util.TransactionUtilities;
import org.balisunrise.application.Application;
import org.balisunrise.builder.BuilderException;
import org.balisunrise.common.VisualAction;
import org.balisunrise.common.Editor;
import org.balisunrise.common.EntityActions;
import org.balisunrise.common.Search;
import org.balisunrise.common.Transaction;
import org.balisunrise.common.TransactionActions;
import org.balisunrise.swing.transaction.panel.TransactionPanel;
import org.balisunrise.swing.transaction.panel.layout.TransactionLayoutBuilder;

/**
 *
 * @author Glauco
 */
public class TransactionBuilder 
        implements org.balisunrise.builder.TransactionBuilder{

    private static final String MESSAGE = "Erro ao construir uma Transaction.\n";

    public Transaction create(Class entityClass, String alias) 
            throws BuilderException {

        if(entityClass == null){
            throw new BuilderException(MESSAGE +
                    "entityClass não pode ser nulo.");
        }

        if(alias == null){
            throw new BuilderException(MESSAGE +
                    "alias não pode ser nulo.");
        }

        TransactionUtilities tu = null;

        try {

            tu = TransactionUtilities.create(entityClass, alias);

        } catch (AnnotationsUtilitiesException ex) {
            
            throw new BuilderException(MESSAGE +
                    ex.getMessage(), ex);
        }

        return create(tu);
    }

    public Transaction create(TransactionUtilities transactionUtilities)
            throws BuilderException {

        if(transactionUtilities == null){
            throw new BuilderException(MESSAGE +
                    "transactionUtilities não pode ser nulo.");
        }

        // Cria Transação
        org.balisunrise.swing.transaction.Transaction t =
                new org.balisunrise.swing.transaction.Transaction();

        // Constrói a Busca
        Search<?,?,?,JPanel> search = Application.get()
                .getVisualEntityManager()
                .getSearchBuilder()
                .create(transactionUtilities.searchUtilities);

        // Constrói o Editor
        Editor<?,?,?,JPanel> editor = Application.get()
                .getVisualEntityManager()
                .getEditorBuilder()
                .create(transactionUtilities.editorUtilities);

        // Constrói as ações
        TransactionActions<org.balisunrise.swing.transaction.Transaction,
                VisualAction,JPanel> ta = Application.get()
                .getVisualEntityManager()
                .getTransactionActionBuilder()
                .create(transactionUtilities.entityClass,
                        transactionUtilities.alias);

        ta.setCreateMethod(transactionUtilities.createMethod);
        ta.setTransaction(t);

        search.setOwner(t);
        editor.setOwner(t);
        ta.setOwner(t);

        // TODO: le mapa de ações e adiciona
//        try{
//            // para cada classe mapa de ação
//            for (Class map : transactionUtilities.actionMaps) {
//                // cria nova instancia
//                Object o = CreateUtilities.newInstance(map,
//                        transactionUtilities.alias);
//                // se for uma instancia de ActionMap
//                if(o instanceof ActionMap){
//                    // Atribui os dados ao ActionMap
//                    ActionMap em = (ActionMap) o;
//                    em.setEntityFilter(search.getEntityFilter());
//                    em.setEntityGrid(search.getEntityGrid());
//                    em.setEntityPanel(editor.getEntityPanel());
//                }
//                // constrói as Ações
//                List<VisualAction> baList = Application.get()
//                        .getVisualEntityManager()
//                        .getVisualActionBuilder()
//                        .create(o, MESSAGE);
//                // adiciona ações
//                for (VisualAction ba : baList) {
//                    ta.addAction(ba);
//                }
//            }
//        }catch(AnnotationsUtilitiesException aue){
//            throw new BuilderException(
//                    MESSAGE + aue.getMessage(),
//                    aue.getCause());
//        }

        // cria ações de confirmação e cancelamento
        String empty = "";
        VisualAction confirmationAction1 = Application.get()
                .getVisualEntityManager()
                .getVisualActionBuilder()
                .createConfirmationAction(ta, empty);
        VisualAction cancellationAction1 = Application.get()
                .getVisualEntityManager()
                .getVisualActionBuilder()
                .createCancellationAction(ta, empty);
        VisualAction confirmationAction2 = Application.get()
                .getVisualEntityManager()
                .getVisualActionBuilder()
                .createConfirmationAction(ta, empty);
        VisualAction cancellationAction2 = Application.get()
                .getVisualEntityManager()
                .getVisualActionBuilder()
                .createCancellationAction(ta, empty);

        // atribui as ações de confirmação e cancelamento
        EntityActions editorAction = editor.getEntityActions();
        confirmationAction1.setOwner(editorAction);
        cancellationAction1.setOwner(editorAction);
        editorAction.setConfirmationAction(confirmationAction1);
        editorAction.setCancellationAction(cancellationAction1);
        // atribui as ações de confirmação e cancelamento
        EntityActions searchAction = search.getEntityActions();
        confirmationAction2.setOwner(searchAction);
        cancellationAction2.setOwner(searchAction);
        searchAction.setConfirmationAction(confirmationAction2);
        searchAction.setCancellationAction(cancellationAction2);
        
        t.setAlias(transactionUtilities.alias);
        t.setEntityClass(transactionUtilities.entityClass);
        t.setTitle(transactionUtilities.title);
        t.setEditor(editor);
        t.setSearch(search);
        t.setTransactionActions(ta);
        t.setVisualRepresentation(new TransactionPanel(
                ta.getVisualRepresentation(),
                editor.getVisualRepresentation(),
                search.getVisualRepresentation(),
                new TransactionLayoutBuilder()));

        // nome da transaction
        String name = NameUtil.buildName(ta);
        t.getVisualRepresentation().setName(name);
        t.getVisualRepresentation().getAccessibleContext().setAccessibleName(name);
        t.setName(name);
        
        return t;
    }

}
